home *** CD-ROM | disk | FTP | other *** search
- TITLE copyfile
-
-
-
- ;Routines
-
- public ERROR_RET_JUMP,COPYFILE,DS1,DS2,AR1,RWLOOP,RWLOOP_EXIT,RETURN
- public ERROR_RET,READWRITE,readwrlp,R_RETURN
-
- ;Variables
-
- public HANDLE1,HANDLE2,SOURCE_FILE,NEW_FILE,BUFFER_SEGMENT
-
- EXTRN BUFFER:WORD
-
- G GROUP CODE
- CODE SEGMENT PUBLIC
- ASSUME DS:G, ES:G, CS:G, SS:G
-
-
- ; function calls
-
- SET_DTA EQU 1AH
- FIND_FIRST_FILE EQU 4EH
- GET_DISK_SPACE EQU 36H
- OPEN_FILE EQU 3DH
- CLOSE_FILE EQU 3EH
- CREATE_FILE EQU 3CH
- DELETE_FILE EQU 41H
- READ_FROM_FILE EQU 3FH
- WRITE_TO_FILE EQU 40H
- ACCESS_DATE_TIME EQU 57H
- DISPLAY_STRING EQU 9
-
- ; error codes
- FILE_NOT_FOUND EQU 11
- INVALID_DRIVE_SPECIFIER EQU 1
- INSUFFICIENT_SPACE EQU 8
- OPEN_ERROR EQU 9
- CREATE_ERROR EQU 10
- DATE_TIME_ERROR EQU 12
- CLOSE_ERROR EQU 13
- DELETE_ERROR EQU 14
- READ_ERROR EQU 16
- WRITE_ERROR EQU 17
-
- DATABLOCK STRUC ; For find first and find next
- DB 21 DUP (?) ;reserved for find_nexts
- ATTRIBUTE DB 0
- TIME DW 0
- DATE DW 0
- LOW_SIZE DW 0
- HIGH_SIZE DW 0
- PNAME DW 13 DUP (?)
- DATABLOCK ENDS
-
- HANDLE1 DW ?
- HANDLE2 DW ?
- SOURCE_FILE DW ?
- NEW_FILE DW ?
- FILEINFO DATABLOCK <,,,,,,>
- BUFFER_SEGMENT DW ?
-
-
- ERROR_RET_JUMP:
- JMP ERROR_RET
-
- ;--------------------------------------------------------------------
-
- COPYFILE PROC
- ; This procedure will copy one file to another. It will check the drive
- ; of the second file to get the amount of disk space available, compare it
- ; to the size of the first file and if the file will fit, copy it to the drive.
- ; call: dx -> source filename
- ; di -> destination filename
- ; Assume the drive letters are capitalized.
- ; return: carry = 1 if an error occurs and al will have the error code
-
- MOV [SOURCE_FILE], DX
- MOV [NEW_FILE], DI
-
- MOV AX, OFFSET G:BUFFER ; Determine the buffer segment
- mov cx,4
- SHR AX,cl
- MOV BX, CS
- ADD BX, AX
- MOV [BUFFER_SEGMENT], BX
-
- MOV AH, SET_DTA
- LEA DX, FILEINFO
- INT 21H
-
- MOV AH, FIND_FIRST_FILE ; get the file size
- MOV DX, [SOURCE_FILE]
- MOV CX, 0 ; find files
- INT 21H
-
- MOV AL, FILE_NOT_FOUND
- JC ERROR_RET_JUMP
-
- CMP BYTE PTR [DI+1], ":" ; get the drive specifier
- ; (default = 0, A = 1, etc
- ; a = 1, b = 2, ... )
- JZ DS1
- MOV DL, 0 ; default
- JMP DS2
-
- DS1:
- MOV DL, BYTE PTR [DI]
- SUB DL, "A"
- INC DL
-
- DS2:
- MOV AH, GET_DISK_SPACE ; get the free disk space
- ; DL = drive specifier
- INT 21H
-
- MOV SI, AX
- CMP AX, 0FFFFH
- MOV AL, INVALID_DRIVE_SPECIFIER
- JZ ERROR_RET_JUMP
- MOV AX, SI
-
- ; ax = sectors per allocation unit
- ; bx = number of free allocation units on drive
- ; cx = bytes per sector
- ; dx = total number of allocation units on drive
-
-
- MUL CX ; free disk bytes = AX * BX * CX
- MUL BX
- MOV BX, AX ; dxbx := free disk bytes
-
- MOV CX, [FILEINFO.HIGH_SIZE] ; compare bytesfree and filesize.
- CMP DX, CX ; If there is not enough space quit.
- MOV AL, INSUFFICIENT_SPACE
- JB ERROR_RET_JUMP
- JA AR1
-
- MOV CX, [FILEINFO.LOW_SIZE]
- CMP BX, CX
- MOV AL, INSUFFICIENT_SPACE
- JBE ERROR_RET_JUMP
-
- AR1:
- MOV AH, OPEN_FILE
- MOV AL, 0 ; access := reading
- MOV DX, [SOURCE_FILE]
- INT 21H
- MOV [HANDLE1], AX
- MOV AL, OPEN_ERROR
- JC ERROR_RET
-
- MOV AH, CREATE_FILE
- MOV DX, [NEW_FILE]
- MOV CX, 0 ; attribute = file type
- INT 21H
- MOV HANDLE2, AX
- MOV AL, CREATE_ERROR
- JC ERROR_RET
-
- MOV SI, [HANDLE1]
- MOV DI, [HANDLE2]
-
- MOV AX, [BUFFER_SEGMENT] ; ds:dx := 64K buffer
- MOV DS, AX
- MOV DX, 0
-
- RWLOOP:
- MOV CX,7800h
- CALL READWRITE
- JC ERROR_RET
-
- CMP CS:[FILEINFO.HIGH_SIZE], WORD PTR 0
- JZ RWLOOP_EXIT
-
- DEC CS:[FILEINFO.HIGH_SIZE]
- JMP RWLOOP
-
- RWLOOP_EXIT:
- MOV AX, CS
- MOV DS, AX
-
- MOV AH, ACCESS_DATE_TIME
- MOV AL, 0 ; get date and time
- MOV BX, [HANDLE1]
- INT 21H
- MOV AL, DATE_TIME_ERROR
- JC ERROR_RET
-
- MOV AL, 1 ; set date and time
- MOV BX, [HANDLE2]
- INT 21H
-
- MOV AH, CLOSE_FILE
- ; BX = handle
- INT 21H
- MOV AL, CLOSE_ERROR
- JC ERROR_RET
-
- MOV AH, CLOSE_FILE
- MOV BX, [HANDLE1] ; close old file to return the handle
- INT 21H
- MOV AL, CLOSE_ERROR
- JC ERROR_RET
-
- MOV AH, DELETE_FILE
- MOV DX, [SOURCE_FILE]
- INT 21H
- MOV AL, DELETE_ERROR
- JC ERROR_RET
-
- RETURN:
- CLC ; clear carry
- RET
-
- ERROR_RET:
- STC
- RET
- COPYFILE ENDP
-
- ;--------------------------------------------------------------------
-
- READWRITE PROC
- ;This subroutine will read from one file the specified number of bytes
- ; and write out the bytes to another file.
- ; call: CX = number of bytes to transfer.
- ; SI = handle of the file to be read from.
- ; DI = handle of the file to be written to.
- ; DS:DX = pointer to a 64K buffer.
- ; return: carry is set if an error occurs in which case al := error code
-
- mov bp,3
- readwrlp:
- MOV AH, READ_FROM_FILE
- MOV BX, SI
- INT 21H
- MOV CX, AX ; AX = number of bytes read
- MOV AL, READ_ERROR
- JC R_RETURN
-
- MOV AH, WRITE_TO_FILE
- MOV BX, DI
- INT 21H
- mov cx,ax
- MOV AL, WRITE_ERROR
- jc r_return ; maybe an error
- dec bp
- jz r_return ; we have done a 16k chunk
- cmp cx,7800h
- jae readwrlp ; do another chunk then
- clc
-
- R_RETURN:
- RET
- READWRITE ENDP
-
- ;--------------------------------------------------------------------
-
- CODE ENDS
- END
-